function deepClone(item) {
  if (!item) return item;
  let result,
    types = [Number, String, Boolean];
  types.forEach(type => {
    if (item instanceof type) {
      result = type(item);
    }
  });
  if (typeof result === "undefined") {
    if (Object.prototype.toString.call(item) === "[object Array]") {
      result = [];
      item.forEach((child, index) => {
        result[index] = deepClone(child);
      });
    } else if (typeof item === "object") {
      if (item.nodeType && typeof item.cloneNode === "function") {
        result = item.cloneNode(true);
      } else if (!item.prototype) {
        if (item instanceof Date) {
          result = new Date(item);
        } else {
          result = {};
          for (let i in item) {
            if (item.hasOwnProperty(i)) {
              result[i] = deepClone(item[i]);
            }
          }
        }
      } else {
        if (item && item.constructor) {
          result = new item.constructor();
        } else {
          result = item;
        }
      }
    } else {
      result = item;
    }
  }
  return result;
}

export const tools = {
  deepClone,
  clone(obj) {
    return JSON.parse(JSON.stringify(obj));
  },
  getId({ str = "id", stamp = 0 }) {
    return str + ((Math.random() + stamp + Date.now()) * 10000).toString(36);
  }
};
